﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace Syspetro.Core.DbAccessor
{
    public interface IRepository<T> where T : EntityBase, new()
    {
        #region 没有事务，直接提交操作
        Guid Add(T data);
        Task<Guid> AddAsync(T data);
        int Add(List<T> datas);
        Task<int> AddAsync(List<T> datas);
        bool Delete(Guid id);
        Task<bool> DeleteAsync(Guid id);
        bool Delete(T data);
        Task<bool> DeleteAsync(T data);
        T Get(Guid id);
        Task<T> GetAsync(Guid id);
        T Get(Expression<Func<T, bool>> expression);
        Task<T> GetAsync(Expression<Func<T, bool>> expression);
        int Delete(Expression<Func<T, bool>> expression);
        Task<int> DeleteAsync(Expression<Func<T, bool>> expression);
        bool Any(Expression<Func<T, bool>> expression);
        Task<bool> AnyAsync(Expression<Func<T, bool>> expression);
        List<T> Find(Expression<Func<T, bool>> expression,string orderby = null, bool isAscending = true);
        Task<List<T>> FindAsync(Expression<Func<T, bool>> expression, string orderby = null, bool isAscending = true);
        List<T> FindPage(out int total, Expression<Func<T, bool>> expression, string orderby, int current, int size, bool isAscending = true);
        bool Update(T data);
        Task<bool> UpdateAsync(T data);
        bool Update(T data, Expression<Func<T, object>> properties, bool isIgnore = false);
        Task<bool> UpdateAsync(T data, Expression<Func<T, object>> properties, bool isIgnore = false);
        int Updates(T data, Expression<Func<T, bool>> expression, Expression<Func<T, object>> properties, bool isIgnore = false);
        Task<int> UpdateAsync(T data, Expression<Func<T, bool>> expression, Expression<Func<T, object>> properties, bool isIgnore = false);
        #endregion

        #region 启用事务提交操作，需要手动Save
        void AddTrans(T data);
        void AddTrans<U>(U data) where U : EntityBase, new();
        void AddTrans(List<T> datas);
        void AddTrans<U>(List<U> datas) where U : EntityBase, new();
        void DeleteTrans(Guid id);
        void DeleteTrans(T data);
        void DeleteTrans<U>(U data) where U : EntityBase, new();
        void DeleteTrans(Expression<Func<T, bool>> expression);
        void DeleteTrans<U>(Expression<Func<U, bool>> expression) where U : EntityBase, new();
        void UpdateTrans(T data);
        void UpdateTrans<U>(U data) where U : EntityBase, new();
        void UpdateTrans(T data, Expression<Func<T, object>> properties, bool isIgnore = false);
        void UpdateTrans<U>(U data, Expression<Func<U, object>> properties, bool isIgnore = false) where U : EntityBase, new();
        int Save { get; }
        Task<int> SaveAsync { get; }
        #endregion

        #region 执行Sql
        DataTable ExecuteSelect(string sql, DbParameter[] pars);
        int ExecuteNonQuery(string sql, DbParameter[] pars);
        Task<DataTable> ExecuteSelectAsync(string sql, DbParameter[] pars);
        Task<int> ExecuteNonQueryAsync(string sql, DbParameter[] pars);
        DataTable ExecuteSelectObject(string sql, object pars);
        int ExecuteNonQueryObject(string sql, object pars);
        Task<DataTable> ExecuteSelectObjectAsync(string sql, object pars);
        Task<int> ExecuteNonQueryObjectAsync(string sql, object pars);
        #endregion

        #region Dto查询
        V GetDto<V>(Guid id) where V : class, new();
        Task<V> GetDtoAsync<V>(Guid id) where V : class, new();
        V GetDto<V>(Expression<Func<T, bool>> expression) where V : class, new();
        Task<V> GetDtoAsync<V>(Expression<Func<T, bool>> expression) where V : class, new();
        List<V> FindDto<V>(Expression<Func<T, bool>> expression, string orderby = null, bool isAscending = true) where V : class, new();
        Task<List<V>> FindDtoAsync<V>(Expression<Func<T, bool>> expression, string orderby = null, bool isAscending = true) where V : class, new();
        List<V> FindPageDto<V>(out int total, Expression<Func<T, bool>> expression, string orderby, int current, int size, bool isAscending = true) where V : class, new();
        #endregion

        #region Dto更新
        int UpdateDto<V>(V data, Expression<Func<T, bool>> expression) where V : new();
        Task<int> UpdateDtoAsync<V>(V data, Expression<Func<T, bool>> expression) where V : new();
        #endregion
    }
}
